SPDX-FileCopyrightText: 2021 Estelle De Vos & Noémie Lobry SPDX-FileCopyrightText: 2024 AlICe laboratory https://alicelab.be
SPDX-License-Identifier: GPL-3.0-or-later
import bpy
import math
import random
bpy.ops.object.select_all(action="SELECT")
bpy.ops.object.delete()
bpy.ops.outliner.orphans_purge()def cube(taille, position):
    bpy.ops.mesh.primitive_cube_add(
        size=taille, enter_editmode=False, location=position, scale=(1, 1, 1)
    )
    bpy.ops.context.renamedef get_objects(name):
    res = []
    for obj in bpy.data.objects:
        if name in obj.name:
            res.append(obj)
    return resdef bool(obj1, obj2):
    bool = obj2.modifiers.new(name="booly", type="BOOLEAN")
    bool.object = obj1
    bool.operation = "INTERSECT"def multi_boolean(collection, object):
    for element in collection:
        bool(object, element)def apply_modifiers(obj):
    ctx = bpy.context.copy()
    ctx["object"] = obj
    for _, m in enumerate(obj.modifiers):
        try:
            ctx["modifier"] = m
            bpy.ops.object.modifier_apply(ctx, modifier=m.name)
        except RuntimeError:
            print(f"Error applying {m.name} to {obj.name}, removing it instead.")
            obj.modifiers.remove(m)
    for m in obj.modifiers:
        obj.modifiers.remove(m)d = 0
inverseur = 1
decalage = 0
for x in range(0, 13):
    d = d + ((x * 2) + 1)
    for onde in range(1, x):
        bpy.ops.mesh.primitive_plane_add(
            size=1, location=(x + d + onde * 0.84 * inverseur, 0, onde)
        )
        bpy.ops.transform.resize(value=(0.75, x, 1))
        bpy.ops.transform.rotate(value=1.39626 * inverseur, orient_axis="Y")
        bpy.context.object.name = "onde" + str(x)
        bpy.ops.mesh.primitive_plane_add(
            size=1,
            location=(
                x + d + onde * 0.84 * inverseur + 0.4,
                0,
                onde + 0.47 * inverseur,
            ),
        )
        bpy.ops.transform.resize(value=(0.75, x, 1))
        bpy.ops.transform.rotate(value=0.349066 * inverseur, orient_axis="Y")
        bpy.context.object.name = "onde" + str(x)
    monOnde = get_objects("onde" + str(x))
    print("monOnde cest", monOnde)
    print("*****************************")
    bpy.ops.object.select_all(action="DESELECT")
    for onde in monOnde:
        onde.select_set(True)
        bpy.context.view_layer.objects.active = onde
    if x >= 8:
        bpy.ops.object.duplicate_move()
        bpy.ops.transform.rotate(value=3.14159, orient_axis="Z")
        bpy.ops.transform.translate(value=(0, 0, 8))
    for onde in monOnde:
        onde.select_set(True)
        bpy.context.view_layer.objects.active = onde
    if x >= 24:
        bpy.ops.object.duplicate_move()
        bpy.ops.transform.rotate(value=3.14159, orient_axis="Z")
        bpy.ops.transform.translate(value=(0, 0, 8))
        inverseur = -inverseurd = 0
inverseur = 1
decalage = 0
for x in range(0, 13):
    d = d + ((x * 2) + 1)
    for onde in range(1, x):
        bpy.ops.mesh.primitive_plane_add(
            size=1, location=(x + d + onde * 0.84 * inverseur, 0, onde)
        )
        bpy.ops.transform.resize(value=(0.75, x, 1))
        bpy.ops.transform.rotate(value=1.39626 * inverseur, orient_axis="Y")
        bpy.ops.transform.translate(value=(x * 0.84, 0, -x))
        bpy.ops.mesh.primitive_plane_add(
            size=1,
            location=(
                x + d + onde * 0.84 * inverseur + 0.4,
                0,
                onde + 0.47 * inverseur,
            ),
        )
        bpy.ops.transform.resize(value=(0.75, x, 1))
        bpy.ops.transform.rotate(value=0.349066, orient_axis="Y")
        bpy.ops.transform.translate(value=(x * 0.84, 0, -x))
    monOnde = get_objects("onde" + str(x))
    bpy.ops.object.select_all(action="DESELECT")
    if x >= 8:
        bpy.ops.object.duplicate_move()
        bpy.ops.transform.rotate(value=3.14159, orient_axis="Z")
        bpy.ops.transform.translate(value=(0, 0, -16))    bpy.ops.object.duplicate_move()
    bpy.ops.transform.rotate(value=0, orient_axis='Z')
                bpy.ops.transform.translate(value=(0, 0, -8))"""
    inverseur = -inverseur
#DIVIDER
bpy.ops.mesh.primitive_plane_add(size=1, location=(125, 0, 0), scale=(1, 1, 1))
bpy.ops.transform.resize(value=(250, 11, 0))
bpy.ops.mesh.primitive_plane_add(size=1, location=(125, 0, 8), scale=(1, 1, 1))
bpy.ops.transform.resize(value=(250, 11, 0))
bpy.ops.mesh.primitive_plane_add(size=1, location=(125, 0, -8), scale=(1, 1, 1))
bpy.ops.transform.resize(value=(250, 11, 0))
bpy.ops.mesh.primitive_plane_add(size=1, location=(125, 0, 24), scale=(1, 1, 1))
bpy.ops.transform.resize(value=(250, 11, 0))
bpy.ops.mesh.primitive_plane_add(size=1, location=(125, 0, -24), scale=(1, 1, 1))
bpy.ops.transform.resize(value=(250, 11, 0))
#DIVIDER
monOnde = get_objects("onde" + str(x))
bpy.ops.object.select_all(action="DESELECT")
for obj in monOnde:
    obj.select_set(True)
    solid = obj.modifiers.new(name="solidy", type="SOLIDIFY")
    solid.thickness = 0.1
    bpy.ops.object.select_all(action="DESELECT")
for obj in monOnde:
    apply_modifiers(obj)
#DIVIDER
taille = 8
horizontal = random.randint(0, 30)
vertical = random.randint(-8, 8)
bpy.ops.mesh.primitive_cube_add(
    size=taille, location=(horizontal, 0, vertical), scale=(5, 5, 5)
)
#DIVIDER
cube = bpy.context.scene.objects.get("Cube")
multi_boolean(monOnde, cube)
#DIVIDER
#DIVIDER
for obj in monOnde:
    apply_modifiers(obj)
#DIVIDER
bpy.ops.object.select_all(action="DESELECT")
cube.select_set(True)
#DIVIDER
#DIVIDER
"""
cube = bpy.context.scene.objects.get("Cube")
multi_boolean(monOnde, cube)bpy.ops.object.select_all(action='SELECT')
for obj in bpy.context.selected_objects:
    obj.name = "Ext"
bpy.ops.object.select_all(action='DESELECT')def boolean (mod, object):  
    bpy.ops.object.modifier_add(type='BOOLEAN')
    bpy.context.object.modifiers["Boolean"].operation = 'INTERSECT'
    bpy.context.object.modifiers["Boolean"].solver = mod
    bpy.context.object.modifiers["Boolean"].object = object
     
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.convert(target='MESH')
bpy.ops.object.join()
bpy.context.active_object.name = 'Ext'Exta = get_objects('Ext')cube (taille, (horizontal,0,vertical))
cube1 = get_objects('Cube')
boolean ('FAST', Exta)cube (10, (horizontal,0,vertical))
cube2 = get_objects('Cube.001')
boolean ('FAST', cube1)Application
bpy.ops.object.modifier_apply(modifier="Boolean")Suppression du cube
cube (10, (horizontal,0,vertical))
boolean ('EXACT', cube2)bpy.ops.object.delete(use_global=False)
bpy.ops.object.modifier_apply(modifier="Boolean")cube.select_set(True)
bpy.ops.transform.translate(value=(0, 50, 0))
bpy.ops.object.select_all(action='DESELECT')
bpy.data.objects['Ext'].select_set(True)
bpy.ops.object.delete(use_global=False)bpy.ops.mesh.primitive_cube_add(size = 1, location = (200,0,-1), scale = (500, 1,30))
cube1.select_set(True)
bpy.ops.object.delete(use_global=False)
cube2.select_set(True)
bpy.ops.object.delete(use_global=False)taille = 40 horizontal = random.randint(0, 200) vertical = random.randint(-8, 8)
bpy.ops.object.select_all(action=”DESELECT”)
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.editmode_toggle()bpy.ops.mesh.normals_make_consistent(inside=True)
bpy.ops.mesh.remove_doubles(threshold=0.001)
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.object.editmode_toggle()Cadrage 1 : première découpe
Cadrage 2 : Cube plus précis mais solver = FAST
for onde in monOnde:
    apply_modifiers(obj)on applique la fonction boolean cette fois seulement
bpy.ops.object.select_all(action='DESELECT')
cube.select_set(True)Cadrage 3 : solver = EXACT
on applique la fonction boolean cette fois seulement
def boolean (mod, object):
    
    bpy.ops.object.modifier_add(type='BOOLEAN')
    bpy.context.object.modifiers["Boolean"].operation = 'INTERSECT'
    bpy.context.object.modifiers["Boolean"].solver = mod
    bpy.context.object.modifiers["Boolean"].object = objectrepositionnement du cube en 0;0
bpy.ops.object.select_all(action='SELECT')
bpy.context.view_layer.objects.active = maCourbeCreeBis
bpy.ops.object.convert(target='MESH')
bpy.ops.object.join()
bpy.context.active_object.name = 'Ext'nettoyage
cube ((5,5, hauteur_cadrage), (12,12,10))
cube1 = get_objects('Cube')[0]
boolean ('FAST', Ext)on referme tous les volumes pour impression
cube ((5,5, hauteur_cadrage), (10.2,10.2,10))
cube2 = get_objects('Cube.001')[0]
boolean ('FAST', cube1)bpy.ops.mesh.edge_face_add()
bpy.ops.object.modifier_apply(modifier="Boolean")cube ((5,5,hauteur_cadrage), (10.2,10.2,10))
boolean ('EXACT', cube2)Application
bpy.ops.object.modifier_apply(modifier="Boolean")Suppression du cube
bpy.ops.transform.translate(value=(0, 0, -hauteur_cadrage+5))
bpy.ops.object.select_all(action='DESELECT')bpy.ops.object.delete(use_global=False)
cube1.select_set(True)
bpy.ops.object.delete(use_global=False)
cube2.select_set(True)
bpy.ops.object.delete(use_global=False)
tour = get_objects('Ext')[0]
tour.select_set(True)
bpy.ops.transform.translate(value=(20, 0, 0 ))bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.editmode_toggle()joindre tous les éléments en un seul objet MESH
bpy.ops.mesh.normals_make_consistent(inside=True)
bpy.ops.mesh.remove_doubles(threshold=0.001)
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.object.editmode_toggle()Cadrage 1 : première découpe
Cadrage 2 : Cube plus précis mais solver = FAST
on applique la fonction boolean cette fois seulement
Cadrage 3 : solver = EXACT
on applique la fonction boolean cette fois seulement
repositionnement du cube en 0;0
nettoyage
on referme tous les volumes pour impression
bpy.ops.mesh.edge_face_add()